package com.feidu.em;

import java.util.Iterator;
import java.util.List;

import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;

import com.feidu.utils.EMSharedPreference;
import com.feidu.utils.MessageID;
import com.hyphenate.EMCallBack;
import com.hyphenate.EMConnectionListener;
import com.hyphenate.EMError;
import com.hyphenate.EMGroupChangeListener;
import com.hyphenate.EMMessageListener;
import com.hyphenate.chat.EMClient;
import com.hyphenate.chat.EMGroup;
import com.hyphenate.chat.EMGroupManager.EMGroupOptions;
import com.hyphenate.chat.EMGroupManager.EMGroupStyle;
import com.hyphenate.chat.EMMessage;
import com.hyphenate.chat.EMMessage.ChatType;
import com.hyphenate.chat.EMOptions;
import com.hyphenate.exceptions.HyphenateException;
/**
 * 
 * 生成日期：2016-7-11 <br/>
 * 描述：环信消息管理类
 */
public class EMHelperManager {

	protected static final String TAG = "EMHelperManager";
	public static EMHelperManager instance = null;

	protected EMMessageListener messageListener = null;// 环信消息监听
	private EMConnectionListener connectionListener;// 监听连接状态的listener
	private String username;// 环信id
	/** 如果sdk已经初始化,我们不需要初始化 **/
	private boolean sdkInited = false;
	private Context context;

	private EMHelperManager() {
		
	}

	public synchronized static EMHelperManager getInstance() {
		if (instance == null) {
			instance = new EMHelperManager();
		}
		return instance;
	}

	/**
	 * 默认初始化环信操作
	 * @param context
	 */
	public void init(Context context) {
		this.context = context;
		EMOptions options = initChatOptions();// 初始化参数
		// 设为调试模式，打成正式包时，最好设为false，以免消耗额外的资源
		if (init(context, options)) {
			EMClient.getInstance().setDebugMode(true);
			// 设置全局监听
			setGlobalListeners(context);
		}

	}
	
	/**
	 *  如果你的 APP 中有第三方的服务启动第二种初始化环信sdk方式
	 *  返回true如果正确初始化，否则false，如果返回为false，请在后续的调用中不要调用任何和环信相关的代码
	 * @param context
	 * @param options 聊天相关的设置，传null则使用默认的
	 * @return
	 */
	public synchronized boolean init(Context context, EMOptions options) {
		if (sdkInited) {
			return true;
		}
		int pid = android.os.Process.myPid();
		String processAppName = getAppName(pid, context);

		Log.d(TAG, "process app name : " + processAppName);

		// 如果app启用了远程的service，此application:onCreate会被调用2次
		// 为了防止环信SDK被初始化2次，加此判断会保证SDK被初始化1次
		// 默认的app会在以包名为默认的process name下运行，如果查到的process name不是app的process
		// name就立即返回
		if (processAppName == null || !processAppName.equalsIgnoreCase(context.getPackageName())) {
			Log.e(TAG, "enter the service process!");

			// 则此application::onCreate 是被service 调用的，直接返回
			return false;
		}
		if (options == null) {
			EMClient.getInstance().init(context, initChatOptions());
		} else {
			EMClient.getInstance().init(context, options);
		}
		sdkInited = true;
		return true;
	}

	/**
	 * 注册连接状态监听
	 * @param context
	 */
	private void setGlobalListeners(final Context context) {
		connectionListener = new EMConnectionListener() {

			// 如果遇到弱网掉线情况，应用收到onDisconnected
			//此时不需要处理重连操作，Hyphenate SDK在底层自动处理重练
			@Override
			public void onDisconnected(int error) {
				// 显示帐号已经被移除
				if (error == EMError.USER_REMOVED) {
					// onCurrentAccountRemoved();
				}
				// 账户在另外一台设备登录
				else if (error == EMError.USER_LOGIN_ANOTHER_DEVICE) {
					
					
				}
			}

			@Override
			public void onConnected() {

			}
		};

		// 注册连接监听
		EMClient.getInstance().addConnectionListener(connectionListener);
		// 注册消息事件监听
		registerEventListener(context);
	}

	private EMOptions initChatOptions() {
		// 获取到EMChatOptions对象
		EMOptions options = new EMOptions();
		// 默认添加好友时，是不需要验证的，改成需要验证
		options.setAcceptInvitationAlways(false);
		// 设置是否需要已读回执
		options.setRequireAck(true);
		// 设置是否需要已送达回执
		options.setRequireDeliveryAck(false);
		//自动登录属性默认是 true 打开的，如果不需要自动登录false
		options.setAutoLogin(false);
		
		return options;
	}

	
	/**
	 * 记得在不需要的时候移除listener，如在activity的onDestroy()时
	 */
	public void removeMessageListener(){
		
		EMClient.getInstance().chatManager().removeMessageListener(messageListener);
	}
	/**
	 * 通过注册消息监听来接收消息
	 */
	protected void registerEventListener(final Context context) {
		messageListener = new EMMessageListener() {

			@Override
			public void onMessageReceived(List<EMMessage> messages) {
				// 收到消息
				for (EMMessage message : messages) {
					
					
				}

			}

			@Override
			public void onMessageReadAckReceived(List<EMMessage> messages) {
				// 收到已读回执

			}

			@Override
			public void onMessageDeliveryAckReceived(List<EMMessage> messages) {
				// 收到已送达回执

			}

			@Override
			public void onMessageChanged(EMMessage messages, Object change) {
				// 消息状态变动

			}

			@Override
			public void onCmdMessageReceived(List<EMMessage> messages) {
				// 收到透传消息

			}
		};
		EMClient.getInstance().chatManager().addMessageListener(messageListener);

	}

	private String getAppName(int pID, Context appContext) {
		String processName = null;
		ActivityManager am = (ActivityManager) appContext.getSystemService(Context.ACTIVITY_SERVICE);
		List l = am.getRunningAppProcesses();
		Iterator i = l.iterator();
		PackageManager pm = appContext.getPackageManager();
		while (i.hasNext()) {
			ActivityManager.RunningAppProcessInfo info = (ActivityManager.RunningAppProcessInfo) (i.next());
			try {
				if (info.pid == pID) {
					CharSequence c = pm.getApplicationLabel(pm.getApplicationInfo(info.processName,
							PackageManager.GET_META_DATA));
					processName = info.processName;
					return processName;
				}
			} catch (Exception e) {
			}
		}
		return processName;
	}

	/**
	 * 注册环信
	 * @param name
	 * @param pwd
	 * @throws HyphenateException
	 */
	public void registerEM(String name,String pwd) throws HyphenateException{
		
			EMClient.getInstance().createAccount(name, pwd);
		
	}
	/**
	 * 登录环信
	 */
	public static void loginEM(final Context context, final String name,String pwd,final Handler mHandler) {
		if (TextUtils.isEmpty(name)) {
			return;
		}
		EMClient.getInstance().login(name, pwd, new EMCallBack() {

			@Override
			public void onSuccess() {
				
				//以下两个方法是为了保证进入主页面后本地会话和群组都 load 完毕
				EMClient.getInstance().groupManager().loadAllGroups();
				EMClient.getInstance().chatManager().loadAllConversations();
				
				EMSharedPreference.setIsLoginState(context, true);
				EMSharedPreference.saveEmoId(context, name);
				
				mHandler.sendEmptyMessage(MessageID.EM_LOGIN_SUCCESS);
			}

			@Override
			public void onProgress(int arg0, String arg1) {

			}

			@Override
			public void onError(int code, String message) {
				Message msg = mHandler.obtainMessage();
				msg.what = MessageID.EM_LOGIN_ERROR;
				msg.arg1 = code;
				mHandler.sendMessage(msg);
			
			}
		});
	}

	/**
	 * 描述：退出环信 <br/>
	 */
	public static void logoutEm(Context context) {
		EMSharedPreference.setIsLoginState(context, false);
		EMClient.getInstance().logout(true, null);
	}
	
	
	/**
	 * 是否登录成功过
	 * 
	 * @return
	 */
	public boolean isLoggedIn() {
		return EMClient.getInstance().isLoggedInBefore();
	}
	
	//-------------------------------------发送消息-------------
	/**
	 * 发送文本消息
	 * @param toChatUsername 为对方用户或者群聊的id，后文皆是如此
	 * @param content为消息文字内容
	 */
	public void sendTextMessage(ChatType chatType,String content,String toChatUsername){
		
		//创建一条文本消息，content为消息文字内容，toChatUsername为对方用户或者群聊的id，后文皆是如此
		EMMessage message = EMMessage.createTxtSendMessage(content, toChatUsername);
		//如果是群聊，设置chattype，默认是单聊
		if ( chatType == ChatType.GroupChat){
			
			message.setChatType(ChatType.GroupChat);
		}
		//发送消息
		EMClient.getInstance().chatManager().sendMessage(message);
	}

	//----------------------------------------群组管理------------------
	
	/**
	 * 创建群组
	 * @param groupName 群组名称
	 * @param desc 群组简介
	 * @param allMembers 群组初始成员，如果只有自己传空数组即可
	 * @param reason 邀请成员加入的reason
	 * @throws HyphenateException 
	 * @return 创建好的group
	 */
	public EMGroup createGroup(String groupName,String desc,String[] allMembers,String reason) throws HyphenateException{
		
		EMGroupOptions option = new EMGroupOptions();
		option.maxUsers = 200;
		/*option里的GroupStyle分别为：
		EMGroupStylePrivateOnlyOwnerInvite——私有群，只有群主可以邀请人；
		EMGroupStylePrivateMemberCanInvite——私有群，群成员也能邀请人进群；
		EMGroupStylePublicJoinNeedApproval——公开群，加入此群除了群主邀请，只能通过申请加入此群；
		EMGroupStylePublicOpenJoin ——公开群，任何人都能加入此群。*/
		option.style = EMGroupStyle.EMGroupStylePrivateMemberCanInvite;
		
		setGroupListener();
		//option群组类型选项，可以设置群组最大用户数(默认200)及群组类型 
		return EMClient.getInstance().groupManager().createGroup(groupName, desc, allMembers, reason, option);
	}
	
	/**
	 * 群组事件监听
	 */
	private void setGroupListener(){
		
		EMClient.getInstance().groupManager().addGroupChangeListener(new EMGroupChangeListener() {
			@Override
			public void onUserRemoved(String groupId, String groupName) {
				//当前用户被管理员移除出群组
			}
			@Override
			public void onInvitationReceived(String groupId, String groupName, String inviter, String reason) {
				//收到加入群组的邀请
			}
			@Override
			public void onInvitationDeclined(String groupId, String invitee, String reason) {
				//群组邀请被拒绝
			}
			@Override
			public void onInvitationAccpted(String groupId, String inviter, String reason) {
				//群组邀请被接受
			}
			@Override
			public void onGroupDestroy(String groupId, String groupName) {
				//群组被创建者解散
			}
			@Override
			public void onApplicationReceived(String groupId, String groupName, String applyer, String reason) {
				//收到加群申请
			}
			@Override
			public void onApplicationAccept(String groupId, String groupName, String accepter) {
				//加群申请被同意
			}
			@Override
			public void onApplicationDeclined(String groupId, String groupName, String decliner, String reason) {
			    // 加群申请被拒绝
			}
			
			//自动同意加入群组 sdk会先加入这个群组，并通过此回调通知应用
			@Override
			public void onAutoAcceptInvitationFromGroup(String arg0,
					String arg1, String arg2) {
				
				
			}
		});
	}
	/**
	 * 设置当前用户的环信id
	 * 
	 * @param username
	 */
	public void setCurrentUserName(String username) {
		EMSharedPreference.setCurrentUserName(context, username);
	}

	/**
	 * 获取当前用户的环信id
	 */
	public String getCurrentUsernName() {
		if (username == null) {
			username = EMSharedPreference.getCurrentUsername(context);
		}
		return username;
	}
	
}